<h2>DESCRIPTION</h2>

<em>v.clean</em> allows the user to automatically fix topology of vector 
maps. Several tools may be listed to be executed sequentially. In this
case, also the threshold parameter requires several values to be listed
accordingly. An error map is optionally written which stores the erroneous
geometries.

<h3>Break lines/boundaries</h3>
<em>tool=break</em>
<p>
The <em>break</em> tool breaks lines/boundaries at intersections and it 
<!-- TODO: what is a collapsed loop?? self-intersecting? -->
also breaks lines/boundaries forming a collapsed loop. 
<!-- TODO: this example is a complete mystery: -->
For example, 0.0;1.0;0.0 is broken at 1.0.
<p>
Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0)
if <em>v.clean</em> is run with several tools.
<p>
Hint: Breaking lines should be followed by removing duplicates, e.g. 
<em>v.clean ... tool=break,rmdupl</em>. If the <em>-c</em> flag is used with 
<em>v.clean ... tool=break</em>, duplicates are automatically removed.

<h3>Remove duplicate geometry features</h3>
<em>tool=rmdupl</em>
<p>
The <em>rmdupl</em> tool removes geometry features with identical 
coordinates. Categories are merged. If a point and a centroid have 
identical coordinates, one of them will be removed if both points and 
centroids are selected with <em>v.clean ... type=point,centroid</em>.
The  same applies for lines and boundaries.
<p>
Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0)
if <em>v.clean</em> is run with several tools.
<p>
The <em>rmdupl</em> tool should be used after breaking lines and 
breaking polygons.

<h3>Remove dangles or change boundary dangles to type line</h3>
<em>tool=rmdangle</em> and <em>tool=chdangle</em>
<p>
A line/boundary is considered to be a dangle if no other line of given 
<em>type</em> is on at least one end node. If a dangle is formed by 
several lines, such a string of lines is taken as one dangle and line 
lengths are summarized. The <em>rmdangle</em> tool deletes a dangle if 
the (combined) length is shorter than <em>thresh</em> or <em>thresh</em> 
&lt; 0. If the combined length is larger than <em>thresh</em>, nothing 
is deleted.
<p>
Threshold has to be given as maximum line/boundary length in map units; 
for latitude-longitude locations in degree. Dangles shorter than
<em>thresh</em> are removed sequentially. All dangles will be removed if
<em>thresh</em> &lt; 0.
<p>
With <em>thresh</em> &lt; 0, only closed loops and lines connecting 
loops will remain. This is useful to remove all incorrect boundaries 
after other cleaning operations with <em>thres</em> is &lt; 0. Areas can 
then be successfully built. 
<p>
To preferentially remove shortest dangles first, a first pass with a 
small <em>thresh</em> value can be followed by subsequent passes with 
higher <em>thresh</em> values. This can be done as one <em>v.clean</em>
job by listing the tool several times and by defining a list of increasing
<em>thresh</em> values.
<p>
The <em>chdangle</em> tool is similar to the <em>rmdangle</em> tool, but 
works only on boundaries and changes dangling boundaries to lines 
instead of removing them.

<h3>Remove or change bridges connecting an area and an island or two islands</h3>
<em>tool=rmbridge</em> and <em>tool=chbridge</em>
<p>
A bridge is an area type connection of an island (polygon in a polygon) 
to the outer polygon. This is topologically incorrect (but OGC Simple 
Features allow it). The <em>rmbridge</em> tool removes bridges and the 
<em>chbridge</em> tool changes bridges to type line:

<div class="code"><pre>
    +-------------+             +-------------+   +-------------+
    |            P|  P: polygon |            P|   |            P|
    |    +---+    |  I: island  |    +---+    |   |    +---+    |
    |    | I |    |  B: bridge  |    | I |    |   |    | I |    |
    |    |   |    |  L: line    |    |   |    |   |    |   |    |
    |    +-+-+    |             |    +---+    |   |    +-.-+    |
    |      |      |             |             |   |      .      |
    |      | B    |             |             |   |      . L    |
    |      |      |             |             |   |      .      |
    +------+------+             +-------------+   +-------------+
</pre></div>
<p>
Islands and areas must be already clean, i.e. without dangles or small 
angles, e.g.
<em>v.clean ... type=boundary tool=rmdangle,rmsa,break,rmdupl,rmbridge 
thresh=-1,0,0,0,0</em>.
<p>
Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0)
if <em>v.clean</em> is run with several tools.

<h3>Snap lines to vertex in threshold</h3>
<em>tool=snap</em>
<p>
The <em>snap</em> tool snaps vertices to another vertex not farther away 
than <em>thresh</em>. If there is no other vertex within <em>thresh</em>, 
no snapping will be done. The <em>type</em> option can have a strong 
influence on the result. A too large threshold and <em>type=boundary</em>
can severely damage area topology, beyond repair.
<p>
Threshold gives maximum distance to another vertex in map units, 
for latitude-longitude locations in degree. 
<p>
Snapped boundaries may need to be cleaned with <em>break,rmdupl,rmsa</em>. 
If the <em>-c</em> flag is used with <em>v.clean tool=snap</em>, the 
sequence of <em>break,rmdupl,rmsa</em> is automatically repeated after 
snapping until no more small angles a left. Additional cleaning with e.g.
<em>tool=rmdangle</em>may be necessary.

<h3>Remove duplicate area centroids</h3>
<em>tool=rmdac</em>
<p>
The <em>rmdac</em> tool removes duplicate area centroids that can result 
from deleting boundaries.
<p>
Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0)
if <em>v.clean</em> is run with several tools.

<h3>Break (topologically clean) areas (imported from a non topological 
format like ShapeFile)</h3>
<em>tool=bpol</em>
<p>
The <em>bpol</em> tool breaks boundaries on each point shared between 2 
and more areas where angles of boundary segments are different and on 
all boundary nodes (start and end points of each boundary). The 
<em>bpol</em> tool behaves similar to <em>break</em> for boundaries, but 
does not break collapsed loops. The <em>bpol</em> tool is faster than 
the <em>break</em> tool but needs more memory.
<p>
Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0)
if <em>v.clean</em> is run with several tools.
<p>
The <em>bpol</em> tool should be followed by <em>rmdupl</em>. If the 
<em>-c</em> flag is used with <em>v.clean ... tool=bpol</em>, duplicates are 
automatically removed.

<h3>Remove vertices in threshold from lines and boundaries</h3>
<em>tool=prune</em>
<p>
The <em>prune</em> tool simplifies lines and boundaries by removing
vertices according to threshold. This tool preserves area topology,
areas are never deleted and centroid attachment is never changed.
<em><a href="v.generalize.html">v.generalize</a></em> offers much more
functionality for line simplification but does not preserve area
topology.

<h3>Remove small areas</h3>
<em>tool=rmarea</em>
<p>
The <em>rmarea</em> tool removes all areas &lt;= <em>thresh</em>. The 
longest boundary with an adjacent area is removed or all boundaries if 
there is no adjacent area. Area categories are not combined when a small 
area is merged with a larger area.
<p>
Threshold must always be in square meters, also for latitude-longitude 
locations or locations with units other than meters.

<h3>Remove all lines or boundaries of zero length</h3>
<em>tool=rmline</em>
<p>
The <em>rmline</em> tool removes all lines or boundaries of zero length 
that may have resulted from other cleaning operations. Zero length 
boundaries are redundant and do not influence area topology.
<p>
Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0)
if <em>v.clean</em> is run with several tools.

<h3>Remove small angles between lines at nodes</h3>
<em>tool=rmsa</em>
<p>
The <em>rmsa</em> tool only concerns angles which are so small that the 
calculated angle is 0. The following figure should help demonstrate what 
the tool does.
<p>
Threshold does not apply, use dummy value if <em>v.clean</em> is 
run with several tools.
<p>
<table><tr><td>
<img src="v_clean_rmsa.png" border=1>
</td></tr>
<tr><td align=center>
<font size=-1><em>tool=rmsa</em></font>
</td></tr>
</table>
<p>
The <em>rmsa</em> tool should be followed by <em>break,rmdupl</em>. The 
<em>rmsa</em> tool followed by <em>break,rmdupl</em> may need to be run 
more than once to remove all small angles. If the <em>-c</em> flag is 
used with <em>v.clean ... tool=rmsa</em>, the sequence of 
<em>rmsa,break,rmdupl</em> is automatically repeated until no more small 
angles a left.

<h2>NOTES</h2>

The user does <b>not</b> have to run <em><a href="v.build.html">v.build</a></em>
on the <em>output</em> vector, unless the <em>-b</em> flag was used. The
<em>-b</em> flag affects <b>only</b> the <em>output</em> vector - 
topology is always built for <em>error</em> vector.


<h2>EXAMPLES</h2>

<h3>Snap lines to vertex in threshold</h3>
<div class="code"><pre>
v.clean input=testmap output=cleanmap tool=snap threshold=1
</pre></div>

<h3>Inspecting the topological errors visually</h3>

Both <em><a href="v.build.html">v.build</a></em> and <em>v.clean</em> can
collect the topological errors into a vector map:

<div class="code"><pre>
v.build -e map=imported error=build_errors
v.clean -c input=imported output=clean error=cleaning_errors tool=snap,rmdangle,rmbridge,chbridge,bpol,prune threshold=5
</pre></div>

The vector maps can be visualized together with the original data
by the following set of display commands:

<div class="code"><pre>
d.vect map=imported color=26:26:26 fill_color=77:77:77 width=5
d.vect map=build_errors color=255:33:36 fill_color=none width=5 icon=basic/point size=30
d.vect map=cleaning_errors color=255:33:36 fill_color=none width=5 icon=basic/point size=30
</pre></div>

<div align="center">
<img src="v_clean.png" alt="topological errors">
<br>
<i>Figure: Topological errors detected in the original data (left)
and cleaned data (right)</i>
</div>

<!--
v.in.ascii -b input=- output=imported format=standard <<EOF
VERTI:
C  1 1
 20.10795595  60.54319764
 1     1
C  1 1
 51.86024171  61.9113356
 1     2
B  10
40.0278379309 74.22082728
40.0278379309 62.1579269574
40.0278379309 55.8642398326
40.5523118579 46.7733584301
34.0838000908 42.5775670136
16.9509851399 45.1999366489
11.1817719422 58.8362587527
13.9789662199 72.1229315717
20.2726533447 75.9690737035
40.0278379309 74.22082728
B  12
37.3774872156 78.2907419083
38.0278379309 75.22082728
41.0278379309 61.1579269574
42.0278379309 56.8642398326
37.5523118579 45.7733584301
47.7201221945 39.7803727359
63.6291646489 52.3677469855
69.573202489 61.9831023151
64.3284632183 67.9271401551
57.6851268088 76.3187229882
45.7970511286 77.7173201271
37.3774872156 78.2907419083
L  3 1
23 30
23 23
23 9
 1     3
L  2 1
65 23
20 23
 1     4
EOF
# v.build shows different set than v.clean, so using both
v.build -e map=imported error=build_errors
v.clean -c input=imported output=clean error=cleaning_errors tool=snap,rmdangle,rmbridge,chbridge,bpol,prune threshold=5

g.region vector=imported e=e+5 w=w-5
d.mon start=cairo output=v_clean.png
d.frame frame=left at=0,100,0,50 -c
d.vect map=imported color=26:26:26 fill_color=77:77:77 width=5
d.vect map=build_errors color=255:33:36 fill_color=none width=5 icon=basic/point size=30
d.vect map=cleaning_errors color=255:33:36 fill_color=none width=5 icon=basic/point size=30
d.frame frame=right at=0,100,50,100 -c
d.vect map=clean color=26:26:26 fill_color=77:77:77 width=5
d.mon stop=cairo

mogrify -trim v_clean.png
pngnq -n 128 -s 3 v_clean.png
optipng -o5 v_clean-nq8.png
mv v_clean-nq8.png v_clean.png
-->

<h3>Cleaning OGR imported data (Simple Feature data) such as SHAPE file</h3>

The import of areas with <em><a href="v.in.ogr.html">v.in.ogr</a> -c</em>
(no cleaning) requires a subsequent run of <em>v.clean</em> to update 
the map to a topologically valid structure (removal of duplicate 
collinear lines etc). The tools used for that are <em>bpol</em> and 
<em>rmdupl</em>:
<div class="code"><pre>
v.clean input=areamap output=areamap_clean tool=bpol,rmdupl type=boundary
</pre></div>

<h3>Extracting intersection points of vector lines</h3>
<div class="code"><pre>
v.clean input=lines1 output=lines2 err=points tool=break type=line
</pre></div>

Intersection points are written to 'points' map.

<h3>Break lines</h3>

<em>v.clean</em> will break the lines where they cross, 
creating new node if needed. Example:

<div class="code"><pre>
v.in.ascii -n out=crossed_lines format=standard &lt;&lt; EOF
L 2
 0 5
 10 5
L 2
 5 0
 5 10
EOF

v.clean in=crossed_lines out=crossed_lines_brk \
        error=intersection tool=break type=line
</pre></div>

<h3>Remove all lines of zero length</h3>

<div class="code"><pre>
v.out.ascii zero format=standard 
L  2 1
 -819832.09065589 -987825.2187231
 -806227.28362601 -971104.80702988
 1     1         
L  2 1
 -799165.24638913 -972974.16982788
 -799165.24638913 -972974.16982788
 1     2         

v.clean input=zero output=zero_clean tool=rmline type=line

v.out.ascii zero_clean format=standard 
L  2 1
 -819832.09065589 -987825.2187231
 -806227.28362601 -971104.80702988
 1     1         
</pre></div>
v.clean type=boundary would remove nothing.

<h3>Repeatedly remove dangling lines up to 50m length</h3>

<div class="code"><pre>
v.clean input=testmap output=cleanmap type=line \
        tool=rmdangle,rmdangle,rmdangle,rmdangle threshold=5,10,20,50
</pre></div>

<h2>SEE ALSO</h2>

<em>
<a href="v.info.html">v.info</a>,
<a href="v.build.html">v.build</a>,
<a href="g.gui.vdigit.html">g.gui.vdigit</a>,
<a href="v.edit.html">v.edit</a>,
<a href="v.generalize.html">v.generalize</a>
</em>

<h2>AUTHORS</h2>

David Gerdes, U.S. Army Construction Engineering Research Laboratory<br>
Radim Blazek, ITC-irst, Trento, Italy<br>
Martin Landa, FBK-irst (formerly ITC-irst), Trento, Italy

<!--
<p>
<i>Last changed: $Date$</i>
-->
